import { BaseView } from './baseview.js'

export class FormView extends BaseView {
  constructor(payload = {}) {
    super(payload)
  }

  get_title({ record }) {
    if (this.config.title) {
      const title = this.config.title
      if (typeof title === 'string') {
        return title
      } else if (typeof title === 'object') {
        const [ntype, ...ns] = Object.keys(title)[0].split('_')
        if (ntype !== 'field') {
          throw 'error'
        }
        const fname = ns.join('_')
        const me = record[fname]
        if (!me) {
          return this.action.title
        }

        const meta = this.metadata[fname] || {}
        if (meta.type === 'many2one') {
          return me.display_name
        } else {
          return me
        }
      } else {
        throw 'error for title'
      }
    } else {
      return this.action.title
    }
  }

  // todo 该函数改为 内部函数.
  get_fields_all(kwargs = {}) {
    const fs = this.fields
    const { editmodel } = kwargs
    if (editmodel) {
      return editmodel.get_fields_all(fs)
    } else {
      return this.Model.get_fields_all(fs)
    }
  }

  _get_kws_for_arch_node(kwargs = {}) {
    const self = this
    function prepare_data() {
      const { record: record0, values: values0, editable } = kwargs

      if (!record0) {
        return { record: undefined, record_onchange: undefined, editable }
      }

      const editmodel = self.new_editmodel()

      const record = editmodel._merge_to_modifiers(record0, values0)
      const record_onchange = editmodel._merge_to_onchange(record0, values0)

      return { editable, record, record_onchange }
    }

    const datas = prepare_data()
    const for_view = datas.record ? 'form.data' : 'form.view'

    const kws2 = { for_view, module: this.module, ...datas }

    return kws2
  }

  _get_arch_sheet(kwargs = {}) {
    const { arch } = this.config
    const { sheet } = arch
    const kws2 = this._get_kws_for_arch_node(kwargs)
    return this.get_arch_for_node(sheet, kws2)
  }

  _get_sheet(kwargs = {}) {
    // 前端 任何变化 都应该刷新 get_sheet
    if (this.check_has_sheet()) {
      return this._get_arch_sheet(kwargs)
    } else {
      const fs = this.get_fields_all(kwargs)

      return Object.keys(fs).reduce((acc, fld) => {
        acc[fld] = {
          ...fs[fld],
          tagname: 'odoofield',
          string: fs[fld].meta.string
        }
        return acc
      }, {})
    }
  }

  get_sheet(kwargs = {}) {
    const children = this._get_sheet(kwargs)
    return {
      children,
      nodename: 'sheet',
      tagname: 'sheet'
    }
  }

  _get_footer(kwargs = {}) {
    const { arch } = this.config
    const { footer = {} } = arch

    const kws2 = this._get_kws_for_arch_node(kwargs)

    const myfooter = this.get_arch_for_node(footer, kws2)

    return myfooter
  }

  get_footer(kwargs = {}) {
    return this._get_footer(kwargs)
  }

  get_box(kwargs = {}) {
    const { arch } = this.config
    const { button_box = {} } = arch

    const kws2 = this._get_kws_for_arch_node(kwargs)

    const box = this.get_arch_for_node(button_box, kws2)

    return box
  }

  _get_header(kwargs = {}) {
    const { arch } = this.config
    if (!arch) {
      console.log('error arch ', this)
      throw 'error arch '
    }
    const { header = {} } = arch
    // console.log('_get_header', header, kwargs)
    const kws2 = this._get_kws_for_arch_node(kwargs)

    const myheader = this.get_arch_for_node(header, kws2)

    return myheader
  }

  get_toolbar(kwargs = {}) {
    const header = this._get_header(kwargs)
    // console.log(header)

    return Object.keys(header).reduce((acc, cur) => {
      const node = header[cur]
      if (node.tagname === 'button') {
        acc[cur] = node
      }
      return acc
    }, {})
  }

  get_statusbar(kwargs = {}) {
    const header = this._get_header(kwargs)

    const statusbar = Object.keys(header).reduce((acc, cur) => {
      const node = header[cur]
      if (node.tagname === 'field' && node.widget === 'statusbar') {
        acc = node
      }
      return acc
    }, undefined)

    if (!statusbar) {
      return undefined
    }

    if (!statusbar.statusbar_visible) {
      return undefined
    }

    const states = statusbar.statusbar_visible.split(',')

    const { record } = kwargs
    if (!states.includes(record.state)) {
      states.push(record.state)
    }

    const sel_get = () => {
      if ('selection' in statusbar) {
        const { selection = [] } = statusbar
        return selection
      } else {
        const { selection = [] } = this.metadata.state
        return selection
      }
    }

    const selection = sel_get()

    const ops = selection.reduce((acc, cur) => {
      acc[cur[0]] = cur[1]
      return acc
    }, {})

    const states2 = states.reduce(
      (acc, cur, index) => {
        const todo = {
          value: cur,
          label: ops[cur],
          index,
          active: cur === record.state
        }

        if (cur === record.state) {
          acc[0] = todo
        }

        acc[1][cur] = todo

        return acc
      },
      [{}, {}]
    )

    return states2
  }

  async load_data(res_id, payload = {}) {
    const context = this.context
    const fields = this.fields
    const kws = { fields, context }
    const res = await this.Model.load_data_one(res_id, kws)
    return res
  }

  //
  // for edit view
  //

  new_editmodel() {
    // call by formview page, click editable button

    const editmodel = this.env.editmodel(this.model, {
      metadata: this.metadata,
      context: this.context
    })

    return editmodel
  }

  get_title_new() {
    return this.config.title_new || '新增'
  }

  get rules() {
    return this.config.rules || {}
  }
}
